package com.imooc.service.impl;

import com.imooc.service.StuService;
import com.imooc.service.TestTransService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TestTransServiceImpl implements TestTransService {

    @Autowired
    private StuService stuService;

    /**
     * 事务的传播机制-propagation
     * required 必需:使用当前事务,如果当前没有事务,这自己新建一个事务,子方法必需运行在一个事务中的,如果当前存在事务,这加入这个事务
     * ,成为一个整体  老板有饭吃,我也有饭吃,如果领导没饭吃,我就自己买饭吃
     * <p>
     * supports: 支持,如果当前有事务,则使用,如果没有则不使用事务,常见查询操作
     * 领导有饭吃分给我,我就吃,没有饭吃,也不强求
     * <p>
     * mandatory: 强制性的,如果当前没有事务,则抛出异常
     * 领导有饭吃,我没啥,没饭吃,我就抛出异常
     * <p>
     * requires_new: 创建一个新事务,如果当前有事务,就会挂起,并创建一个新事务,也就是两个独立,如果没有事务那就和required一样
     * 领导有饭而且分给我,我不要这碗饭,另外买饭吃,如果他没饭吃,我也会自己买
     * <p>
     * not_supported: 不支持,如果当前有事务,则把事务挂起
     * 领导有饭吃,分给我我也不吃,没饭吃,我也不会自己买饭吃
     * <p>
     * never: 从不使用事务,如果有事务就抛异常
     * 如果领导有饭分给我吃,我就抛异常
     * <p>
     * nested: 嵌入的,嵌套的 如果当前有事务,则开启一个子事务,和requires_new 有区别,嵌套事务是独立提交或者回滚,如果没有事务,则如同required
     * 如果主方法发生异常,那么嵌套事务也会被影响的
     * 如果主事务提交,也会携带子事务提交
     * 如果主事务回滚,子事务也会回滚,如果子事务异常,则父事务可以选择回滚或者不会滚,只需要try-catch就行
     * 领导决策错误,领导带着小弟受罪,小弟出了差错,则领导可以分担责任或者让其背锅
     */
    //加了事务以后,该方法的内部方法调用也使用了事务机制,抛出异常后发生了回滚
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void testPropagationTrans() {
        stuService.saveParent();
        stuService.saveChildren();
    }
}